"""
通知服务
处理工单相关的多通道通知（飞书、邮件、短信）
"""

from typing import Optional, Dict, Any
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
# import aiosmtplib
import asyncio
# from twilio.rest import Client

from src.config.settings import settings
from src.models.ticket import Ticket, TicketReply
from src.models.user import User
from src.services.feishu_service import FeishuService
from src.utils.logging import get_logger

logger = get_logger(__name__)


class NotificationService:
    """通知服务类"""
    
    @staticmethod
    async def notify_ticket_created(ticket: Ticket, created_by: User) -> bool:
        """通知工单创建"""
        message = f"""
        🎫 新工单已创建
        
        工单编号: #{str(ticket.id)[:8]}
        标题: {ticket.title}
        优先级: {ticket.priority.value}
        分类: {ticket.category.value}
        创建人: {created_by.display_name or created_by.username}
        
        描述:
        {ticket.description[:200]}...
        """
        
        success = True
        
        # 飞书通知
        try:
            feishu_service = FeishuService()
            feishu_service.send_text_message(
                "oc_1234567890",  # 替换为实际的飞书群ID
                f"新工单创建通知: {ticket.title}\n{message.strip()}",
                "user_id"
            )
        except Exception as e:
            logger.error(f"飞书通知发送失败: {e}")
            success = False
        
        # 邮件通知（给客服和管理员）
        if settings.SMTP_USERNAME and settings.SMTP_PASSWORD:
            try:
                await NotificationService.send_email_notification(
                    subject=f"新工单: {ticket.title}",
                    message=message,
                    to_emails=["support@example.com"]  # 实际使用时替换为客服邮箱
                )
            except Exception as e:
                logger.error(f"邮件通知发送失败: {e}")
                success = False
        
        # 短信通知（紧急工单）
        if (ticket.priority in ["high", "urgent"] and 
            settings.TWILIO_ACCOUNT_SID and settings.TWILIO_AUTH_TOKEN):
            try:
                await NotificationService.send_sms_notification(
                    message=f"紧急工单创建: {ticket.title}",
                    to_phone="+8612345678900"  # 实际使用时替换为客服手机号
                )
            except Exception as e:
                logger.error(f"短信通知发送失败: {e}")
                success = False
        
        return success
    
    @staticmethod
    async def notify_ticket_updated(ticket: Ticket, updated_by: User) -> bool:
        """通知工单更新"""
        message = f"""
        🔄 工单已更新
        
        工单编号: #{str(ticket.id)[:8]}
        标题: {ticket.title}
        状态: {ticket.status.value}
        更新人: {updated_by.display_name or updated_by.username}
        
        当前状态: {ticket.status.value}
        """
        
        if ticket.assigned_to:
            message += f"\n分配给了: {ticket.assigned_to.display_name or ticket.assigned_to.username}"
        
        success = True
        
        # 飞书通知
        try:
            feishu_service = FeishuService()
            feishu_service.send_text_message(
                "oc_1234567890",  # 替换为实际的飞书群ID
                f"工单更新通知: {ticket.title}\n{message.strip()}",
                "user_id"
            )
        except Exception as e:
            logger.error(f"飞书通知发送失败: {e}")
            success = False
        
        return success
    
    @staticmethod
    async def notify_ticket_reply(ticket: Ticket, reply: TicketReply, replied_by: User) -> bool:
        """通知工单回复"""
        message = f"""
        💬 工单有新回复
        
        工单编号: #{str(ticket.id)[:8]}
        标题: {ticket.title}
        回复人: {replied_by.display_name or replied_by.username}
        
        回复内容:
        {reply.content[:200]}...
        """
        
        success = True
        
        # 飞书通知
        try:
            feishu_service = FeishuService()
            feishu_service.send_text_message(
                "oc_1234567890",  # 替换为实际的飞书群ID
                f"工单回复通知: {ticket.title}\n{message.strip()}",
                "user_id"
            )
        except Exception as e:
            logger.error(f"飞书通知发送失败: {e}")
            success = False
        
        # 邮件通知给工单创建者（如果不是回复者本人）
        # 修复类型检查问题，先获取ticket.created_by.email的值
        creator_email = None
        if ticket.created_by and hasattr(ticket.created_by, 'email'):
            creator_email = ticket.created_by.email
            
        if (str(ticket.created_by_id) != str(replied_by.id) and 
            settings.SMTP_USERNAME and settings.SMTP_PASSWORD and
            creator_email):
            try:
                await NotificationService.send_email_notification(
                    subject=f"工单回复: {ticket.title}",
                    message=message,
                    to_emails=[creator_email]
                )
            except Exception as e:
                logger.error(f"邮件通知发送失败: {e}")
                success = False
        
        return success
    
    @staticmethod
    async def send_email_notification(
        subject: str, 
        message: str, 
        to_emails: list[str]
    ) -> bool:
        """
        发送邮件通知
        """
        # 检查必要的配置是否存在
        if not settings.SMTP_USERNAME or not settings.SMTP_PASSWORD or \
           not settings.SMTP_SERVER or not settings.SMTP_PORT:
            logger.warning("邮件配置不完整，跳过发送邮件")
            return False
            
        try:
            # 创建邮件对象
            msg = MIMEMultipart()
            msg['From'] = settings.SMTP_USERNAME or ""
            msg['To'] = ', '.join(to_emails)
            msg['Subject'] = subject
            
            # 添加邮件正文
            msg.attach(MIMEText(message, 'plain', 'utf-8'))
            
            # 连接SMTP服务器并发送邮件
            # 注意：在实际生产环境中，应该使用异步SMTP库如aiosmtplib
            # 这里为了简化，使用同步方式并在异步函数中执行
            loop = asyncio.get_event_loop()
            await loop.run_in_executor(
                None, 
                NotificationService._send_email_sync, 
                msg
            )
            return True
        except Exception as e:
            logger.error(f"邮件发送失败: {e}")
            return False
    
    @staticmethod
    def _send_email_sync(msg):
        """
        同步发送邮件的辅助方法
        """
        try:
            server = smtplib.SMTP(settings.SMTP_SERVER or "", settings.SMTP_PORT or 587)
            server.starttls()
            server.login(settings.SMTP_USERNAME or "", settings.SMTP_PASSWORD or "")
            server.send_message(msg)
            server.quit()
        except Exception as e:
            logger.error(f"同步邮件发送失败: {e}")
            raise

    @staticmethod
    async def send_sms_notification(
        message: str,
        to_phone: str
    ) -> bool:
        """
        发送短信通知 (使用Twilio)
        """
        # 检查必要的配置是否存在
        if not settings.TWILIO_ACCOUNT_SID or not settings.TWILIO_AUTH_TOKEN:
            logger.warning("短信配置不完整，跳过发送短信")
            return False
            
        try:
            # 注意：这里需要安装twilio库并配置相关参数
            # pip install twilio
            # import aiosmtplib
            # from twilio.rest import Client
            
            # client = Client(settings.TWILIO_ACCOUNT_SID, settings.TWILIO_AUTH_TOKEN)
            # message = client.messages.create(
            #     body=message,
            #     from_=settings.TWILIO_PHONE_NUMBER,
            #     to=to_phone
            # )
            # 为避免引入额外依赖，这里仅记录日志
            logger.info(f"短信发送（模拟）: {message} 到 {to_phone}")
            return True
        except Exception as e:
            logger.error(f"短信发送失败: {e}")
            return False

    @staticmethod
    async def notify_ticket_assigned(ticket: Ticket, assigned_to: User) -> bool:
        """通知工单分配"""
        message = f"""
        👤 工单已分配
        
        工单编号: #{str(ticket.id)[:8]}
        标题: {ticket.title}
        优先级: {ticket.priority.value}
        分配给了: {assigned_to.display_name or assigned_to.username}
        
        请及时处理此工单。
        """
        
        success = True
        
        # 飞书通知给被分配人
        try:
            feishu_service = FeishuService()
            feishu_service.send_text_message(
                "oc_1234567890",  # 替换为实际的飞书群ID
                f"工单分配通知: {ticket.title}\n{message.strip()}",
                "user_id"
            )
        except Exception as e:
            logger.error(f"飞书通知发送失败: {e}")
            success = False
            
        return success

    @staticmethod
    async def send_proactive_recommendation(user: User, recommendation: Dict[str, Any]) -> bool:
        """
        发送主动推荐通知
        
        Args:
            user: 用户对象
            recommendation: 推荐内容
            
        Returns:
            是否发送成功
        """
        try:
            title = recommendation.get("title", "为您推荐")
            description = recommendation.get("description", "")
            service_type = recommendation.get("service", "general")
            
            message = f"""
            🔍 主动推荐
            
            {title}
            
            {description}
            
            """
            
            success = True
            sent_channels = []
            
            # 飞书通知
            try:
                feishu_service = FeishuService()
                feishu_service.send_text_message(
                    "oc_1234567890",  # 替换为实际的飞书群ID
                    f"主动推荐: {title}\n{description}",
                    "user_id"
                )
                sent_channels.append("feishu")
            except Exception as e:
                logger.error(f"飞书主动推荐通知发送失败: {e}")
                success = False
            
            # 邮件通知
            user_email = getattr(user, 'email', None)
            if settings.SMTP_USERNAME and settings.SMTP_PASSWORD and user_email:
                try:
                    await NotificationService.send_email_notification(
                        subject=f"主动推荐: {title}",
                        message=message,
                        to_emails=[user_email]
                    )
                    sent_channels.append("email")
                except Exception as e:
                    logger.error(f"邮件主动推荐通知发送失败: {e}")
                    success = False
            
            # 短信通知 (如果用户设置了手机号)
            user_phone = getattr(user, 'phone', None)
            if user_phone and hasattr(settings, 'TWILIO_ACCOUNT_SID') and settings.TWILIO_ACCOUNT_SID:
                try:
                    await NotificationService.send_sms_notification(
                        message=f"主动推荐: {title} - {description}",
                        to_phone=user_phone
                    )
                    sent_channels.append("sms")
                except Exception as e:
                    logger.error(f"短信主动推荐通知发送失败: {e}")
                    # 短信发送失败不标记为整体失败
            
            # 记录发送日志
            logger.info(f"向用户 {user.id} 发送主动推荐通知，渠道: {', '.join(sent_channels)}")
            
            return success
        except Exception as e:
            logger.error(f"发送主动推荐通知失败: {e}")
            return False